/******************************************************************************
 * This file is part of libemb.
 *
 * libemb is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * libemb is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with libemb.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Project: Embedme
 * Author : FergusZeng
 * Email  : cblock@126.com
 * git	  : https://gitee.com/newgolo/embedme.git
 * Copyright 2014~2020 @ ShenZhen ,China
*******************************************************************************/
#include "libemb/Tracer.h"
#include "libembx/Config.h"

namespace libembx{
using namespace std;
using namespace libemb;
/**
 *  @brief  Settings构造函数
 *  @param  root 配置根结点
 *  @return none
 */
Settings::Settings(libconfig::Setting* root):
m_root(root)
{
}
/**
 *  @brief  Settings拷贝构造函数
 *  @param  settings拷贝对象
 *  @return none
 */
Settings::Settings(const Settings& settings)
{
    m_root = settings.m_root;
    m_keyword = settings.m_keyword;
}
/**
 *  @brief  Settings析构函数
 *  @param  none
 *  @return none
 */
Settings::~Settings()
{
}

/**
 *  @brief  []运算符重载,获取数组或列表元素
 *  @param  idx 索引
 *  @return 返回索引为idx的数组或列表元素
 */
Settings Settings::operator[](int idx)
{
    if(m_root!=NULL && m_root->exists(m_keyword))
    {
        int type = (*m_root)[m_keyword].getType();
        switch (type)
        {
            case libconfig::Setting::TypeNone:      /* 0: none */
            case libconfig::Setting::TypeInt:       /* 1: int */
            case libconfig::Setting::TypeInt64:     /* 2: int64 */
            case libconfig::Setting::TypeFloat:     /* 3: float&double */
            case libconfig::Setting::TypeString:    /* 4: string */
            case libconfig::Setting::TypeBoolean:   /* 5: boolean */
            case libconfig::Setting::TypeGroup:     /* 6: 配置组 */
            case libconfig::Setting::TypeArray:     /* 7: 数组 */
            {
                return (*this);
            }
            case libconfig::Setting::TypeList:      /* 8: 列表(包含多个配置组) */
            {
                libconfig::Setting* setting = &((*m_root)[m_keyword][idx]);
                Settings settings(setting);
                return settings;
            }
        }
    }
    else
    {
        TRACE_ERR_CLASS("Setting[%s][%d] not exist!\n",CSTR(m_keyword),idx);
        return (*this);
    }
    return (*this);
}
/**
 *  @brief  []运算符重载,获取配置项
 *  @param  keyword 配置项名称关键字
 *  @return 返回配置项
 */
Settings Settings::operator[](string keyword)
{
    if (m_root!=NULL)
    {
        if(m_root->exists(keyword))
        {
            int type = (*m_root)[keyword].getType();
            switch (type)
            {
                case libconfig::Setting::TypeNone:      /* 0: none */
                case libconfig::Setting::TypeInt:       /* 1: int */
                case libconfig::Setting::TypeInt64:     /* 2: int64 */
                case libconfig::Setting::TypeFloat:     /* 3: float&double */
                case libconfig::Setting::TypeString:    /* 4: string */
                case libconfig::Setting::TypeBoolean:   /* 5: boolean */
                case libconfig::Setting::TypeArray:     /* 7: 数组 */
                case libconfig::Setting::TypeList:      /* 8: 列表(包含多个配置组) */
                {
                    m_keyword=keyword;
                    return (*this);
                }
                
                case libconfig::Setting::TypeGroup:     /* 6: 配置组 */
                {
                    libconfig::Setting* setting = &((*m_root)[keyword]);
                    Settings settings(setting);
                    settings.m_keyword = keyword;
                    return settings;
                }
            }
        }
        else
        {
            m_keyword = keyword;
            return (*this);
        }
        
    }
    else
    {
        TRACE_ERR_CLASS("Empty Setting !\n");
        return (*this);
    }
    return (*this);
}
/**
 *  @brief  判断是否存在配置项
 *  @param  name 配置项名称
 *  @return 存在返回true,否则返回false
 */
bool Settings::exists(string name)
{
    if (m_root!=NULL)
    {
        if (m_root->exists(name))
        {
            return true;
        }
    }
    return false;
}

std::string Settings::name()
{
	return m_keyword;
}

/**
 *  @brief  获取数组或列表长度(元素个数)
 *  @param  none
 *  @return 返回长度,否则返回0
 */
int Settings::size()
{
    if (m_root!=NULL && m_root->exists(m_keyword))
    {
        if((*m_root)[m_keyword].getType()==libconfig::Setting::TypeArray ||
            (*m_root)[m_keyword].getType()==libconfig::Setting::TypeList)
        {
            return (*m_root)[m_keyword].getLength();
        }
    }
    return 0;
}

/**
 *  @brief  获取配置项整数值
 *  @param  none
 *  @return 返回配置项整数值
 */
int Settings::toInt()
{
    int result=0;
    if (m_root!=NULL && m_root->exists(m_keyword))
    {
        if((*m_root)[m_keyword].getType()==libconfig::Setting::TypeInt)
        { 
            m_root->lookupValue(m_keyword,result);
        }
        else
        {
            TRACE_ERR_CLASS("Setting[%s] wrong type:%d!\n",CSTR(m_keyword),(*m_root)[m_keyword].getType()); 
        }
    }
    else
    {
        TRACE_ERR_CLASS("Setting[%s] not exist!\n",CSTR(m_keyword));
    }
    return result;
}

/**
 *  @brief  获取配置项浮点值
 *  @param  none
 *  @return 返回配置项浮点值
 */
double Settings::toDouble()
{
    double result=0.0;
    if (m_root!=NULL && m_root->exists(m_keyword))
    {
        if((*m_root)[m_keyword].getType()==libconfig::Setting::TypeFloat)
        { 
            m_root->lookupValue(m_keyword,result);
        }
        else
        {
            TRACE_ERR_CLASS("Setting[%s] wrong type:%d!\n",CSTR(m_keyword),(*m_root)[m_keyword].getType()); 
        }
    }
    else
    {
        TRACE_ERR_CLASS("Setting[%s] not exist!\n",CSTR(m_keyword));
    }
    return result;
}
/**
 *  @brief  获取配置项字符串值
 *  @param  none
 *  @return 返回配置项字符串值
 */
string Settings::toString()
{
    string result="";
    if (m_root!=NULL && m_root->exists(m_keyword))
    {
        if((*m_root)[m_keyword].getType()==libconfig::Setting::TypeString)
        { 
            m_root->lookupValue(m_keyword,result);
        }
        else
        {
            TRACE_ERR_CLASS("Setting[%s] wrong type:%d!\n",CSTR(m_keyword),(*m_root)[m_keyword].getType()); 
        }
    }
    else
    {
        TRACE_ERR_CLASS("Setting[%s] not exist!\n",CSTR(m_keyword));
    }
    return result;
}

/**
 *  @brief  获取配置项整数数组值
 *  @param  none
 *  @return 返回配置项整数数组值
 */
IntArray Settings::toIntArray()
{
    IntArray result;
    if (m_root!=NULL && m_root->exists(m_keyword))
    {
        if((*m_root)[m_keyword].getType()==libconfig::Setting::TypeArray)
        { 
            for (auto i=0; i<(*m_root)[m_keyword].getLength(); i++)
        	{
        		result.append((*m_root)[m_keyword][i]);
            }
        }
        else
        {
            TRACE_ERR_CLASS("Setting[%s] wrong type:%d!\n",CSTR(m_keyword),(*m_root)[m_keyword].getType()); 
        }
    }
    else
    {
        TRACE_ERR_CLASS("Setting[%s] not exist!\n",CSTR(m_keyword));
    }
    return result;   
}

/**
 *  @brief  获取配置项浮点数组值
 *  @param  none
 *  @return 返回配置项浮点数组值
 */
DoubleArray Settings::toDoubleArray()
{
    DoubleArray result;
    if (m_root!=NULL && m_root->exists(m_keyword))
    {
        if((*m_root)[m_keyword].getType()==libconfig::Setting::TypeArray)
        { 
            for (auto i=0; i<(*m_root)[m_keyword].getLength(); i++)
        	{
        		result.append((*m_root)[m_keyword][i]);
            }
        }
        else
        {
            TRACE_ERR_CLASS("Setting[%s] wrong type:%d!\n",CSTR(m_keyword),(*m_root)[m_keyword].getType()); 
        }
    }
    else
    {
        TRACE_ERR_CLASS("Setting[%s] not exist!\n",CSTR(m_keyword));
    }
    return result;   
}

/**
 *  @brief  获取配置项字符串数组值
 *  @param  none
 *  @return 返回配置项字符串数组值
 */
StringArray Settings::toStringArray()
{
    StringArray result;
    if (m_root!=NULL && m_root->exists(m_keyword))
    {
        if((*m_root)[m_keyword].getType()==libconfig::Setting::TypeArray)
        { 
            for (auto i=0; i<(*m_root)[m_keyword].getLength(); i++)
        	{
        		result.append((*m_root)[m_keyword][i]);
            }
        }
        else
        {
            TRACE_ERR_CLASS("Setting[%s] wrong type:%d!\n",CSTR(m_keyword),(*m_root)[m_keyword].getType()); 
        }
    }
    else
    {
        TRACE_ERR_CLASS("Setting[%s] not exist!\n",CSTR(m_keyword));
    }
    return result;   
}

/**
 *  @brief  增加整数配置项
 *  @param  keyword 配置名称
 *  @param  value 配置值
 *  @return 成功返回true,失败返回false
 */
bool Settings::addInt(const string& keyword,int value)
{
    if (keyword.empty())
    {
        TRACE_ERR_CLASS("keyword is empty!\n");
        return false;
    }
    if (m_root!=NULL)
    {
        if (m_root->exists(keyword))
        {
            TRACE_ERR_CLASS("Setting[%s] is exist!\n",CSTR(keyword));
            return false;
        }
        else
        {
            if (m_root->getType()==libconfig::Setting::TypeGroup ||m_keyword.empty())
            {
                /* 当根结点是组时或者直接就是根配置(此时m_root非组,m_keyword为空)时,直接增加 */
                m_root->add(keyword,libconfig::Setting::TypeInt);
                (*m_root)[keyword] = value;
                return true;
            }
            else
            {
                switch ((*m_root)[m_keyword].getType())
                {
                    case libconfig::Setting::TypeGroup:     /* 6: 配置组 */
                        break;
                    default:
                        TRACE_ERR_CLASS("Setting[%s] is not group!\n",CSTR(m_keyword));
                        return false;
                }
                (*m_root)[m_keyword].add(keyword,libconfig::Setting::TypeInt);
                (*m_root)[m_keyword][keyword]=value;
            }
            return true;
        }
    }
    else
    {
        TRACE_ERR_CLASS("Null Setting!\n");
    }
    return false;  
}

/**
 *  @brief  增加浮点数配置项
 *  @param  keyword 配置名称
 *  @param  value 配置值
 *  @return 成功返回true,失败返回false
 */
bool Settings::addDouble(const string& keyword,double value)
{
    if (keyword.empty())
    {
        TRACE_ERR_CLASS("keyword is empty!\n");
        return false;
    }
    if (m_root!=NULL)
    {
        if (m_root->exists(keyword))
        {
            TRACE_ERR_CLASS("Setting[%s] is exist!\n",CSTR(keyword));
            return false;
        }
        else
        {
            /* 当根结点是组时或者直接就是根配置(此时m_root非组,m_keyword为空)时,直接增加 */
            if (m_root->getType()==libconfig::Setting::TypeGroup || m_keyword.empty())
            {
                m_root->add(keyword,libconfig::Setting::TypeFloat);
                (*m_root)[keyword] = value;
                return true;
            }
            else
            {
                switch ((*m_root)[m_keyword].getType())
                {
                    case libconfig::Setting::TypeGroup:     /* 6: 配置组 */
                        break;
                    default:
                        TRACE_ERR_CLASS("Setting[%s] is not group!\n",CSTR(m_keyword));
                        return false;
                }
                (*m_root)[m_keyword].add(keyword,libconfig::Setting::TypeFloat);
                (*m_root)[m_keyword][keyword]=value;
            }
            return true;
        }
    }
    else
    {
        TRACE_ERR_CLASS("Null Setting!\n");
    }
    return false;  
}
/**
 *  @brief  增加字符串配置项
 *  @param  keyword 配置名称
 *  @param  value 配置值
 *  @return 成功返回true,失败返回false
 */
bool Settings::addString(const string& keyword,const string& value)
{
    if (keyword.empty())
    {
        TRACE_ERR_CLASS("keyword is empty!\n");
        return false;
    }
    if (m_root!=NULL)
    {
        if (m_root->exists(keyword))
        {
            TRACE_ERR_CLASS("Setting[%s] is exist!\n",CSTR(keyword));
            return false;
        }
        else
        {
            /* 当根结点是组时或者直接就是根配置(此时m_root非组,m_keyword为空)时,直接增加 */
            if (m_root->getType()==libconfig::Setting::TypeGroup || m_keyword.empty())
            {
                m_root->add(keyword,libconfig::Setting::TypeString);
                (*m_root)[keyword] = value;
                return true;
            }
            else
            {
                switch ((*m_root)[m_keyword].getType())
                {
                    case libconfig::Setting::TypeGroup:     /* 6: 配置组 */
                        break;
                    default:
                        TRACE_ERR_CLASS("Setting[%s] is not group!\n",CSTR(m_keyword));
                        return false;
                }
                (*m_root)[m_keyword].add(keyword,libconfig::Setting::TypeString);
                (*m_root)[m_keyword][keyword]=value;
            }
            return true;
        }
    }
    else
    {
        TRACE_ERR_CLASS("Null Setting!\n");
    }
    return false;  
}
#if 0
/**
 *  @brief  增加数组配置项
 *  @param  keyword 配置名称
 *  @param  value 配置值
 *  @return 成功返回true,失败返回false
 */
bool Settings::addArray(const string& keyword,Array& value)
{
    if (keyword.empty())
    {
        TRACE_ERR_CLASS("keyword is empty!\n");
        return false;
    }
    if (m_root!=NULL)
    {
        if (m_root->exists(keyword))
        {
            TRACE_ERR_CLASS("Setting[%s] is exist!\n",CSTR(keyword));
            return false;
        }
        else
        {
            /* 当根结点是组时或者直接就是根配置(此时m_root非组,m_keyword为空)时,直接增加 */
            if (m_root->getType()==libconfig::Setting::TypeGroup || m_keyword.empty())
            {
                m_root->add(keyword,libconfig::Setting::TypeArray);
                for(auto i=0; i<value.size(); i++)
                {
                    switch(value.type())
                    {
                        case BASETYPE_INTARRAY:
                             (*m_root)[keyword].add(libconfig::Setting::TypeInt);
                             (*m_root)[keyword][i] = ((IntArray&)value)[i];
                             break;
                        case BASETYPE_DOUBLEARRAY:
                             (*m_root)[keyword].add(libconfig::Setting::TypeFloat);
                             (*m_root)[keyword][i] = ((DoubleArray&)value)[i];
                             break;
                        case BASETYPE_STRINGARRAY:
                             (*m_root)[keyword].add(libconfig::Setting::TypeString);
                             (*m_root)[keyword][i] = ((StringArray&)value)[i];
                             break;
                        default:
                            return false;
                    }
                }
                return true;
            }
            else
            {
                switch ((*m_root)[m_keyword].getType())
                {
                    case libconfig::Setting::TypeGroup:     /* 6: 配置组 */
                        break;
                    default:
                        TRACE_ERR_CLASS("Setting[%s] is not group!\n",CSTR(m_keyword));
                        return false;
                }
                (*m_root)[m_keyword].add(keyword,libconfig::Setting::TypeArray);
                for(auto i=0; i<value.size(); i++)
                {
                	switch(value.type())
                    {
                        case BASETYPE_INTARRAY:
                             (*m_root)[keyword].add(libconfig::Setting::TypeInt);
                             (*m_root)[keyword][i] = ((IntArray&)value)[i];
                             break;
                        case BASETYPE_DOUBLEARRAY:
                             (*m_root)[keyword].add(libconfig::Setting::TypeFloat);
                             (*m_root)[keyword][i] = ((DoubleArray&)value)[i];
                             break;
                        case BASETYPE_STRINGARRAY:
                             (*m_root)[keyword].add(libconfig::Setting::TypeString);
                             (*m_root)[keyword][i] = ((StringArray&)value)[i];
                             break;
                        default:
                            return false;
                    }
                }
                return true;
            }
        }
    }
    else
    {
        TRACE_ERR_CLASS("Null Setting!\n");
    }
    return false;  
}
#endif
/**
 *  @brief  增加列表配置项
 *  @param  keyword 配置名称
 *  @return 成功返回true,失败返回false
 */
bool Settings::addList(const string& keyword)
{
    if (keyword.empty())
    {
        TRACE_ERR_CLASS("keyword is empty!\n");
        return false;
    }
    if (m_root!=NULL)
    {
        if (m_root->exists(keyword))
        {
            TRACE_ERR_CLASS("Setting[%s] is exist!\n",CSTR(keyword));
            return false;
        }
        else
        {
            /* 当根结点是组时或者直接就是根配置(此时m_root非组,m_keyword为空)时,直接增加 */
            if (m_root->getType()==libconfig::Setting::TypeGroup || m_keyword.empty())
            {
                m_root->add(keyword,libconfig::Setting::TypeList);
                return true;
            }
            else
            {
                switch ((*m_root)[m_keyword].getType())
                {
                    case libconfig::Setting::TypeGroup:     /* 6: 配置组 */
                        break;
                    default:
                        TRACE_ERR_CLASS("Setting[%s] is not group!\n",CSTR(m_keyword));
                        return false;
                }
                (*m_root)[m_keyword].add(keyword,libconfig::Setting::TypeList);
                return true;
            }
        }
    }
    else
    {
        TRACE_ERR_CLASS("Null Setting!\n");
    }
    return false;
}
/**
 *  @brief  增加组配置项
 *  @param  keyword 关键字
 *  @return 成功返回true,失败返回false
 *  \note   当keyword为空时,给列表增加无名组.非空,增加普通有名组.
 */
bool Settings::addGroup(const string& keyword)
{
    if (keyword.empty())
    {
        if (m_root!=NULL && !m_keyword.empty())
        {
            switch ((*m_root)[m_keyword].getType())
            {
                case libconfig::Setting::TypeList:
                    break;
                default:
                    TRACE_ERR_CLASS("Setting[%s] is not a list!\n",CSTR(m_keyword));
                    return false;
            }
            (*m_root)[m_keyword].add(libconfig::Setting::TypeGroup);
            return true;
        }
        TRACE_ERR_CLASS("keyword is empty!\n");
        return false;
    }
    if (m_root!=NULL)
    {
        if (m_root->exists(keyword))
        {
            TRACE_ERR_CLASS("Setting[%s] is exist!\n",CSTR(keyword));
            return false;
        }
        else
        {
            /* 当根结点是组时或者直接就是根配置(此时m_root非组,m_keyword为空)时,直接增加 */
            if (m_root->getType()==libconfig::Setting::TypeGroup || m_keyword.empty())
            {
                m_root->add(keyword,libconfig::Setting::TypeGroup);
                return true;
            }
            else
            {
                switch ((*m_root)[m_keyword].getType())
                {
                    case libconfig::Setting::TypeGroup:     /* 6: 配置组 */
                        break;
                    default:
                        TRACE_ERR_CLASS("Setting[%s] is not group!\n",CSTR(m_keyword));
                        return false;
                }
                (*m_root)[m_keyword].add(keyword,libconfig::Setting::TypeGroup);
                return true;
            } 
        }
    }
    else
    {
        TRACE_ERR_CLASS("Null Setting!\n");
    }
    return false;
}

/**
 *  @brief  等号运算符重载,设置整数值
 *  @param  value 整数值
 *  @return 返回当前Settings引用
 */
Settings& Settings::operator=(const int& value)
{
    if (m_root!=NULL && m_root->exists(m_keyword))
    {
        if((*m_root)[m_keyword].getType()==libconfig::Setting::TypeInt)
        { 
            (*m_root)[m_keyword]= value;
        }
        else
        {
            TRACE_ERR_CLASS("Setting[%s] wrong type:%d!\n",CSTR(m_keyword),(*m_root)[m_keyword].getType()); 
        }
    }
    else
    {
        TRACE_ERR_CLASS("Setting[%s] not exist!\n",CSTR(m_keyword));
    }
    return (*this);
}
/**
 *  @brief  等号运算符重载,设置浮点数值
 *  @param  value 浮点数值
 *  @return 返回当前Settings引用
 */
Settings& Settings::operator=(const double& value)
{
    if (m_root!=NULL && m_root->exists(m_keyword))
    {
        if((*m_root)[m_keyword].getType()==libconfig::Setting::TypeFloat)
        { 
            (*m_root)[m_keyword]= value;
        }
        else
        {
            TRACE_ERR_CLASS("Setting[%s] wrong type:%d!\n",CSTR(m_keyword),(*m_root)[m_keyword].getType()); 
        }
    }
    else
    {
        TRACE_ERR_CLASS("Setting[%s] not exist!\n",CSTR(m_keyword));
    }
    return (*this);
}
/**
 *  @brief  等号运算符重载,设置字符串值
 *  @param  value 字符串值
 *  @return 返回当前Settings引用
 */
Settings& Settings::operator=(const string& value)
{
    if (m_root!=NULL && m_root->exists(m_keyword))
    {
        if((*m_root)[m_keyword].getType()==libconfig::Setting::TypeString)
        { 
            (*m_root)[m_keyword]= value;
        }
        else
        {
            TRACE_ERR_CLASS("Setting[%s] wrong type:%d!\n",CSTR(m_keyword),(*m_root)[m_keyword].getType()); 
        }
    }
    else
    {
        TRACE_ERR_CLASS("Setting[%s] not exist!\n",CSTR(m_keyword));
    }
    return (*this);
}
/**
 *  @brief  等号运算符重载,设置整型数组值
 *  @param  value 整型数组值
 *  @return 返回当前Settings引用
 */
Settings& Settings::operator=(IntArray& value)
{
    if (m_root!=NULL && m_root->exists(m_keyword))
    {
        if((*m_root)[m_keyword].getType()==libconfig::Setting::TypeArray)
        {
            int arraySize = (*m_root)[m_keyword].getLength();
            for(auto i=0; i<value.size(); i++)
            {
                if(i>=arraySize)
                {
                    (*m_root)[m_keyword].add(libconfig::Setting::TypeInt);
                }
                (*m_root)[m_keyword][i] = value[i];
            }
        }
        else
        {
            TRACE_ERR_CLASS("Setting[%s] wrong type:%d!\n",CSTR(m_keyword),(*m_root)[m_keyword].getType()); 
        }
    }
    else
    {
        TRACE_ERR_CLASS("Setting[%s] not exist!\n",CSTR(m_keyword));
    }
    return (*this);
}

/**
 *  @brief  设置根结点
 *  @param  root 根结点
 *  @return none
 */
void Settings::setRoot(libconfig::Setting* root)
{
    /* 只可以设置一次 */
    if (m_root==NULL)
    {
        m_root = root;
    }
}


/**
 *  @brief  等号运算符重载,设置浮点数组值
 *  @param  value 浮点数组值
 *  @return 返回当前Settings引用
 */
Settings& Settings::operator=(DoubleArray& value)
{
    if (m_root!=NULL && m_root->exists(m_keyword))
    {
        int arraySize = (*m_root)[m_keyword].getLength();
        if((*m_root)[m_keyword].getType()==libconfig::Setting::TypeArray)
        { 
            for(auto i=0; i<value.size(); i++)
            {
                if(i>=arraySize)
                {
                    (*m_root)[m_keyword].add(libconfig::Setting::TypeFloat);
                }
                (*m_root)[m_keyword][i] = value[i];
            }
        }
        else
        {
            TRACE_ERR_CLASS("Setting[%s] wrong type:%d!\n",CSTR(m_keyword),(*m_root)[m_keyword].getType()); 
        }
    }
    else
    {
        TRACE_ERR_CLASS("Setting[%s] not exist!\n",CSTR(m_keyword));
    }
    return (*this);
}

/**
 *  @brief  Config构造函数
 *  @param  none
 *  @return none
 */
Config::Config()
{
    m_config = std::make_unique<libconfig::Config>();
    m_setting = std::make_unique<Settings>();
    m_nullsetting = std::make_unique<Settings>((libconfig::Setting*)NULL);
}
/**
 *  @brief  Config析构函数
 *  @param  none
 *  @return none
 */
Config::~Config()
{
}

/**
 *  @brief  初始化配置
 *  @param  cfgFile 配置文件名称
 *  @return 成功返回true,失败返回false
 */
bool Config::initWithFile(const string& cfgFile)
{
    if (m_rootSetting!=NULL ||
        cfgFile.empty())
    {
        TRACE_ERR_CLASS("Config root exists or file not exist:%s.\n",CSTR(cfgFile));
        return false;
    }
    try
    {
        m_config->readFile(CSTR(cfgFile));
    }
    catch (const libconfig::FileIOException& ex)
    {
        TRACE_ERR_CLASS("Read config faild:%s, error(%s).\n",CSTR(cfgFile),ex.what());
        return false;
    }
    catch (const libconfig::ParseException& ex)
    {
        TRACE_ERR_CLASS("Parse config  failed:%s, line[%d],err[%s],error(%s)\n",CSTR(cfgFile),ex.getLine(),ex.getError(),ex.what());
        return false;
    }
    try
    {
        m_rootSetting = &m_config->getRoot();
    }
    catch (const libconfig::ConfigException& ex)
    {
        TRACE_ERR_CLASS("Get config root failed:%s, error(%s).\n",CSTR(cfgFile),ex.what());
        return false;
    }
    m_setting->setRoot(m_rootSetting);
    return true;
}

/**
 *  @brief  保存配置
 *  @param  cfgFile 配置文件名称
 *  @return 成功返回true,失败返回false
 *  \note   可以多次调用
 */
bool Config::saveAsFile(const string& cfgFile)
{
    if (cfgFile.empty())
    {
        TRACE_ERR_CLASS("Save config failed:file name empty!\n");
        return false;
    }

    try
    {
        m_config->writeFile(CSTR(cfgFile));
    }
    catch(const libconfig::FileIOException& ex)
    {
        TRACE_ERR_CLASS("Write config failed:%s, error(%s)!\n",CSTR(cfgFile),ex.what());
        return false;  
    }
    return true;
}
/**
 *  @brief  []运算符重载,获取配置项
 *  @param  keyword 配置项名称
 *  @return 返回配置项
 */
Settings Config::operator[](string keyword)
{
    if (m_rootSetting==NULL)
    {
        try
        {
            m_rootSetting = &m_config->getRoot();
        }
        catch (const libconfig::ConfigException& ex)
        {
            TRACE_ERR_CLASS("Get config[\"%s\"] root failed, error(%s).\n",CSTR(keyword),ex.what());
            return (*m_nullsetting)[""]; ;
        }
        m_setting->setRoot(m_rootSetting);
    }
    try
    {
        if (m_rootSetting->exists(keyword))
        {
            return (*m_setting)[keyword];
        }
        else
        {
            TRACE_ERR_CLASS("Empty Config:%s!\n",CSTR(keyword));
            return (*m_nullsetting)[""];
        }
    }
    catch(const libconfig::ConfigException &ex)
    {
        TRACE_ERR_CLASS("Config[\"%s\"] IO failed,error:%s",CSTR(keyword),ex.what());
        return (*m_nullsetting)[""];   
    }
}
/**
 *  @brief  获取根配置
 *  @param  none
 *  @return 返回根配置项
 */
Settings Config::rootSettings()
{
    if (m_rootSetting==NULL)
    {
        try
        {
            m_rootSetting = &m_config->getRoot();
        }
        catch (const libconfig::ConfigException& ex)
        {
            TRACE_ERR_CLASS("Get config root failed, error(%s).\n",ex.what());
            return (*m_nullsetting);
        }
        m_setting->setRoot(m_rootSetting);
    }
    return (*m_setting)[""];
}
}